﻿using System.Collections.Generic;
using Jayden.Dll.Core.Membership;
using Jayden.Dll.Web.Enums;
using Jayden.Dll.Web.HtmlControls;
using Jayden.Dll.Web.Json;

namespace Jayden.Dll.Web.Controls
{
	public class MenuOl : Ol
	{

		public override void Load(System.Xml.XmlNode node, HtmlControlLoader loader)
		{
			base.Load(node, loader);
			if (Id == null)
				Id = "menuOl";
		}

		public override void ProcessHtmlRequest(HttpHandlerContext context)
		{
			base.ProcessHtmlRequest(context);
			LoginForm.LoginCommandHandler login = context.HandlerManager.GetHandler<LoginForm.LoginCommandHandler>();
			LogoutA.LogoutCommandHandler logout = context.HandlerManager.GetHandler<LogoutA.LogoutCommandHandler>();
			login.LoginSuccess += new LoginForm.OnLoginSuccess(LoginSuccess);
			logout.Logout += new LogoutA.OnLogout(Logout);
			SetMenu(context.Context.User.Identity.IsAuthenticated, context.User == null ? null : context.User.RoleNames);
		}

		public override void ProcessJsonRequest(HttpHandlerContext context)
		{
			base.ProcessJsonRequest(context);
			LoginForm.LoginCommandHandler login = context.HandlerManager.GetHandler<LoginForm.LoginCommandHandler>();
			login.LoginSuccess += new LoginForm.OnLoginSuccess(LoginSuccess);
			LogoutA.LogoutCommandHandler logout = context.HandlerManager.GetHandler<LogoutA.LogoutCommandHandler>();
			logout.Logout += new LogoutA.OnLogout(Logout);
		}

		public override void ProcessJsRequest(HttpHandlerContext context)
		{
			base.ProcessJsRequest(context);
			if (!context.Js.Contains(Id))
			{
				context.Js[Id].AppendAjaxHtmlHandler(this, false, false);
				context.Js[Id].AppendOnInit(@"$('#" + Id + @"').on('click', 'a[data-ajax=""true""]', JAYDEN.sfn.clickAjax);");
			}
		}

		protected void SetMenu(bool authenticated, HashSet<string> roles)
		{
			List<Li> toRemove = new List<Li>();
			foreach (Li li in GetControls<Li>())
			{
				if (li.ServerAuthenticated && !authenticated)
					li.ServerRender = false;
				else if (li.ServerNotAuthenticated && authenticated)
					li.ServerRender = false;
				else
				{
					li.ServerRender = true;
					string queryRoles = li.GetServerAttribute("roles");
					if (!string.IsNullOrWhiteSpace(queryRoles))
					{
						if (roles != null)
						{
							string[] requiredRoles = queryRoles.Split(',');
							foreach (string role in requiredRoles)
								if (!roles.Contains(role))
								{
									li.ServerRender = false;
									break;
								}
						} else
							li.ServerRender = false;
					}
				}
				if (li.ServerRender)
					foreach (SubMenuUl subMenu in li.GetControls<SubMenuUl>())
						subMenu.SetMenu(authenticated, roles);
			}
		}

		private void Logout(HttpHandlerContext context)
		{
			SetMenu(false, null);
			if (context.RequestType == HttpRequestType.Json)
			{
				JsonObject menu = new JsonObject();
				menu.Add("html", ToInnerHtml(context.Translator));
				context.Json.Add(Id, menu);
			}
		}

		private void LoginSuccess(HttpHandlerContext context, User user)
		{
			SetMenu(true, user.RoleNames);
			if (context.RequestType == HttpRequestType.Json)
			{
				JsonObject menu = new JsonObject();
				menu.Add("html", ToInnerHtml(context.Translator));
				context.Json.Add(Id, menu);
			}
		}
	}

	public class SubMenuUl : Ul
	{
		public void SetMenu(bool authenticated, HashSet<string> roles)
		{
			List<Li> toRemove = new List<Li>();
			foreach (Li li in GetControls<Li>())
			{
				if (li.ServerAuthenticated && !authenticated)
					li.ServerRender = false;
				else if (li.ServerNotAuthenticated && authenticated)
					li.ServerRender = false;
				else
				{
					li.ServerRender = true;
					string queryRoles = li.GetServerAttribute("roles");
					if (!string.IsNullOrWhiteSpace(queryRoles))
					{
						if (roles != null)
						{
							string[] requiredRoles = queryRoles.Split(',');
							foreach (string role in requiredRoles)
								if (!roles.Contains(role))
								{
									li.ServerRender = false;
									break;
								}
						}
						else
							li.ServerRender = false;
					}
				}
				if(li.ServerRender)
					foreach (SubMenuUl subMenu in li.GetControls<SubMenuUl>())
						subMenu.SetMenu(authenticated, roles);

			}
		}
	}
}
